package com.ppt.android.base.utils

import android.annotation.SuppressLint
import java.security.SecureRandom
import java.util.Base64
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec

/**
 *
 *  val secretKey = AESUtils.generateKey()
 *  val iv = AESUtils.generateIv()
 *
 *  val input = "Hello, world!"
 *  val encrypted = AESUtils.encrypt(input, secretKey, iv)
 *  val decrypted = AESUtils.decrypt(encrypted, secretKey, iv)
 *
 *  println("Input: $input")
 *  println("Encrypted: $encrypted")
 *  println("Decrypted: $decrypted")
 *
 *
 * @author ZouJiaCai
 * @since 2023/6/8 20:59
 */
object AESUtils {

    private const val ALGORITHM = "AES"
    private const val TRANSFORMATION = "AES/CBC/PKCS5Padding"

    fun generateKey(): SecretKey {
        val keyGenerator = KeyGenerator.getInstance(ALGORITHM)
        keyGenerator.init(256)
        return keyGenerator.generateKey()
    }

    fun generateIv(): ByteArray {
        val iv = ByteArray(16)
        SecureRandom().nextBytes(iv)
        return iv
    }

    @SuppressLint("NewApi")
    fun encrypt(input: String, secretKey: SecretKey, iv: ByteArray): String {
        val cipher = Cipher.getInstance(TRANSFORMATION)
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, IvParameterSpec(iv))
        val encryptedBytes = cipher.doFinal(input.toByteArray(Charsets.UTF_8))
        return Base64.getEncoder().encodeToString(encryptedBytes)
    }

    @SuppressLint("NewApi")
    fun decrypt(input: String, secretKey: SecretKey, iv: ByteArray): String {
        val cipher = Cipher.getInstance(TRANSFORMATION)
        cipher.init(Cipher.DECRYPT_MODE, secretKey, IvParameterSpec(iv))
        val decodedBytes = Base64.getDecoder().decode(input)
        val decryptedBytes = cipher.doFinal(decodedBytes)
        return String(decryptedBytes, Charsets.UTF_8)
    }

    /**
     * 自定义偏移向量
     */
    private fun getCustomIv(): ByteArray {
        return "zHUR+iIEHEDBxS48".toByteArray(Charsets.UTF_8)
    }

    /**
     * val secretKey = "RHc5jPOGuNyH0uNi"
     * val input = "Hello, world!"
     * val encrypted = AESUtils.encrypt(input, secretKey, fixedIv)
     */
    @SuppressLint("NewApi")
    fun encrypt(input: String, secretKey: String = "RHc5jPOGuNyH0uNi", iv: ByteArray = getCustomIv()): String {
        val cipher = Cipher.getInstance(TRANSFORMATION)
        val keySpec = SecretKeySpec(secretKey.toByteArray(Charsets.UTF_8), ALGORITHM)
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, IvParameterSpec(iv))
        val encryptedBytes = cipher.doFinal(input.toByteArray(Charsets.UTF_8))
        return Base64.getEncoder().encodeToString(encryptedBytes)
    }

    /**
     * AES加密
     */
    @SuppressLint("NewApi")
    fun encrypt(strToEncrypt: String, secretKey: String? = null) : String? {
        try {
            var secretKey = secretKey?: "WRSvnoclqglHG1yn"
            val key = SecretKeySpec(secretKey.toByteArray(charset("UTF-8")), "AES")
            val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
            cipher.init(Cipher.ENCRYPT_MODE, key)
            return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.toByteArray(charset("UTF-8"))))
        } catch (e: Exception) {
            println("Error while encrypting: $e")
        }
        return null
    }
}